<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/box.css">
    <link rel="stylesheet" href="css/table.css">
    <style>
        .container {
            width: 100vw;
            height: 100vh;
        }

        .main {
            width: 100%;
            height: 80%;
            border: 1px solid #000;
            overflow: hidden;
            position: relative;

        }

        .content {
            width: 10000px;
            height: 10000px;
            background-color: rgba(0, 0, 0, .1);
            position: relative;
            transform-origin: 0 0;
            top: 0;
            left: 0;
        }

        #parent {
            width: 100%;
            position: relative;
            /*border: 1px solid #000;*/
            margin: 0;
            -webkit-font-smoothing: antialiased;
        }

        .redBox {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 100px;
            left: 100px;
        }

        .blackBox {
            width: 100px;
            height: 100px;
            background-color: black;
            position: absolute;
            top: 100px;
            left: 210px;
        }

        .control {
            position: fixed;
            top: 20px;
            right: 50px;
            width: auto;
            height: 50px;
            display: flex;
            flex-direction: row;
            justify-content: space-around;
            align-items: center;
            background-color: #fff;
        }

        .control .btn {
            cursor: pointer;
            padding: 0 12px;
        }
    </style>
    <script src="js/jquery-1.11.0.min.js"></script>
    <script src="js/jquery-magnet.min.js"></script>
    <script src="js/jquery-plugin.js"></script>
    <script type="text/javascript" src="js/device2.js"></script>
</head>
<body>
<div class="container">
    <div class="main">
        <div class="content">
            <div id="parent">
                <div id="lines">
                    <span class="vert"></span>
                    <span class="hori"></span>
                </div>
                <div id="paper">
                    <div id="canvasBox"></div>
                </div>
            </div>

        </div>
    </div>
    <div class="control">
        <div class="btn" onclick="amplify(1)">+</div>
        <div class="btn" onclick="amplify(2)">-</div>
        <div class="btn" onclick="getTableData()">获取表格数据</div>
    </div>
</div>
<script>
    //页面缩放
    var scale = 1
    var amplify = function (num) {
        if (num == 1) {
            if (scale >= 1.8) {
                return false
            }
            scale = Number((scale + 0.1).toFixed(1))
            changeScale(scale)
        } else {
            if (scale <= 0.6) {
                return false
            }
            scale = Number((scale - 0.1).toFixed(1))
            changeScale(scale)
        }

    }
    var changeScale = function (scale){
        $('.content').css({
            '-webkit-transform': 'scale(' + scale + ')',
            '-moz-transform': 'scale(' + scale + ')',
            '-ms-transform': 'scale(' + scale + ')',
            '-o-transform': 'scale(' + scale + ')',
            'transform': 'scale(' + scale + ')'
        })
    }
</script>
<script>
    (($) => {
        var myTiming;//鼠标悬浮出弹窗 页面定时器
        const itemBox = {
            width: 150,
            height: 100
        };//定义设备模块大小
        const $window = $(window);
        const $magnet = $.magnet({
            distance: 10,//吸附距离初始值
            stayInParent: false,//固定画布初始值
            alignOuter: true,//外部对其初始值
            alignInner: false,//内部对齐初始值
            alignParentCenter: false,//盒子父级居中对齐
            alignCenter: false,//父级居中对齐
        });

        $window.on('load', () => {
            const $canvasBox = $('#canvasBox');
            const $mask = $('#lines');
            const $horiMagnet = $mask.find('.hori');
            const $vertMagnet = $mask.find('.vert');

            $magnet
                .on('start change end', ({type}) => {
                    console.log(`magnet${type}`);
                })
                .on('end', () => {
                    $horiMagnet.removeClass('show');
                    $vertMagnet.removeClass('show');
                })
                .on('change', (e) => {
                    console.log('$magnet change',)
                    // show/hide horizon/vertical edge line
                    let result = e.detail;
                    let resultX = result.x;
                    let resultY = result.y;
                    if (resultX) {
                        $vertMagnet.css('left', (resultX.position + 'px'));
                        $vertMagnet.addClass('show');
                    } else {
                        $vertMagnet.removeClass('show');
                    }
                    if (resultY) {
                        $horiMagnet.css('top', (resultY.position + 'px'));
                        $horiMagnet.addClass('show');
                    } else {
                        $horiMagnet.removeClass('show');
                    }
                });


            //初始化设备
            (function addEle() {
                console.log('数据=', deviceJson)
                for (let i = 0; i < deviceJson.length; i++) {
                    addBox(deviceJson[i])
                }
                addFun()
            })()

            //创建box
            function addBox(option) {
                console.log('看看拖动又没触发？')
                const {row, column, childList, name, left, top} = option;
                const rootWidth = $window.width();
                const rootHeight = $window.height();

                const width = itemBox.width * column + column * 10; //盒子宽
                const height = itemBox.height * row + row * 10 + 20; //盒子高
                //监听dom变化  创建一个链接到回调函数的观察者实例
                var observer = new MutationObserver(function (mutationsList) {
                    mutationsList.forEach(function (item, index) {
                        if (item.type == 'attributes') {
                            console.log(item)
                            console.log('修改了' + item.attributeName + '属性',);
                            if ($(item.target)[0].style.width != width + 'px') {
                                $(item.target)[0].style.width = width + 'px'
                                $(item.target)[0].style.height = Number(height + 10) + 'px'
                            }
                        }
                    });
                })
                //创建 checkbox
                var inset = ''
                const $checkbox = $('<input>')
                    .attr('type', 'checkbox')
                    .prop('checked', false)
                    .on('mousedown touchstart', (evt) => evt.stopPropagation())
                    .on('change', function (e) {
                        if (this.checked) {
                            console.log('兄弟选择器', $(this).next()[0].dataset)
                            let data = $(this).next()[0].dataset
                            inset = inset != '' ? inset : `${data.top}px auto auto ${data.left}px`

                            let block = this.parentElement;
                            $(this).next().css({"pointer-events": "none"});
                            $magnet.add(block);
                            $(block)[0].style.width = width + 'px'
                            $(block)[0].style.height = Number(height + 10) + 'px'
                            $(block)[0].style.inset = inset
                        } else {
                            console.log('兄弟选择器', this.parentNode.style.inset)
                            inset = this.parentNode.style.inset
                            let block = this.parentNode;
                            block.style.resize = 'none';//设定用户可调整元素的高度和宽度。
                            $magnet.remove(block);
                            // $(block)[0].style.width = width+'px'
                            // $(block)[0].style.height = Number(height + 10)+'px'
                            $(block)[0].style.inset = `${inset.top}px auto auto ${inset.left}px`
                            $(this).next().css({"pointer-events": "auto"});
                            observer.disconnect();
                        }
                    });
                const $block = $('<span>')
                    .css({
                        width: width + 'px',
                        height: Number(height + 10) + `px`,
                        left: left + `px`,
                        top: top + `px`,
                        backgroundColor: `rgba(0, 0, 0, .1)`,
                    })
                    .addClass('block')
                    .on('mousedown', function (e) {
                        console.log('鼠标按下', this.style.height)
                        this.style.width = width + 'px'
                        this.style.height = Number(height + 10) + 'px'
                        this.style.zIndex = 10;
                        // 开始观察已配置突变的目标节点
                        observer.observe(this, {attributes: true, childList: false, subtree: false});
                    })
                    .on('mouseup', function (e) {
                        console.log('鼠标抬起', this.style.height)
                        observer.disconnect();
                        this.style.width = width + 'px'
                        this.style.height = Number(height + 10) + 'px'
                        this.style.zIndex = 1;
                    })
                    .mouseenter(function (e) {
                        console.log('鼠标划入事件')
                    })
                    .on('click', function () {
                        console.log('block点击')
                        $(this).parent().append(this);
                        this.style.zIndex = 1;
                        this.style.width = width + 'px'
                        this.style.height = Number(height + 10) + 'px'
                    })
                    .on('attract unattract attracted unattracted', function (e) {
                        console.log(e.type, e);
                        this.style.width = width + 'px'
                        this.style.height = Number(height + 10) + 'px'
                    })
                    .append($checkbox)
                    .appendTo($canvasBox);

                let parentLength = $("div[class='parent']").length;//当前页面 有几个 parent
                var $parent = $('<div class="parent" data-action="' + name + '"data-top="' + top + '"data-left="' + left + '" data-row="' + row + '" data-column="' + column + '" style="width: ' + Number(column * itemBox.width + column * 10) + 'px;margin-top: 30px;"></div>')
                let A_Z = 'ABCDEFGHIJKLMNOPKRSTUVWXYZ'
                let a_z = 'abcdefghijklmnopkrstuvwxyz'
                for (let i = 0; i < childList.length; i++) {
                    console.log('输出status=', childList[i].objData ? childList[i]['objData']['status'] : '没有objData')
                    let seachImg = childList[i].objData ? childList[i]['objData']['status'] == 1 ? 'img/computer-no.png' : 'img/computer-off.png' : 'img/computer-off.png'
                    let onAndOff = childList[i].objData ? childList[i]['objData']['status'] == 1 ? 'on' : 'off' : 'off'
                    let isRun = childList[i].objData ? childList[i]['objData']['status'] == 1 ? '运行中' : '已关机' : '已关机'
                    let id = childList[i].objData ? childList[i].objData.id : ''
                    let objname = childList[i].objData ? childList[i].objData.name : ''
                    let item1 = `<div class="list_name" data-id="` + id + `">` + objname + `</div>` +
                        `<img src="` + seachImg + `" alt="" class="comp_img">` +
                        ` <div class="status ` + onAndOff + `"><div class="circle"></div>` + isRun + `</div>`
                    let haveDom = childList[i].objData ? item1 : ''
                    let str = `<div class="item" data-parent="` + name + `" data-position="` + childList[i].position + `">` + haveDom + `</div>`
                    console.log('str=', str)
                    let $item = $(str)
                    $parent.append($item)
                }
                $block.append($parent)
                return $block;
            }


            var Astop = true;
            var Parent = '', toParent = '';

            //添加 设备 拖拽事件
            function addFun() {

                $('#canvasBox .item').on('mousedown', function (e) {
                        if (Astop) {
                            console.log('鼠标点击下的even 参数=',e)
                            if (e.offsetX <= 10 || e.offsetY <= 10) return //防止误操作 故改为距离边框 4 才可进行拖拽操作
                            Parent = $(this)[0].dataset.parent //当前要替换的dom 的 父ID
                            Astop = false;
                            let that = this;
                            let disx = e.offsetX; //获取的拖拽过程的短线的长度（鼠标的位置离盒子边缘的位置）
                            let disy = e.offsetY;
                            let disx2 = e.clientX; //获取的拖拽过程的短线的长度（鼠标的位置离盒子边缘的位置）
                            let disy2 = e.clientY;
                            /*获取当前拖拽的dom的页面位置 begin*/
                            let thatGrandPosition = $(that).parent().parent().position()
                            let thatPosition = $(that).position()
                            let animatePosition = {
                                top: thatGrandPosition.top + thatPosition.top,
                                left: thatGrandPosition.left + thatPosition.left,
                            }
                            /*获取当前拖拽的dom的页面位置 end*/
                            let $clone = $(this).clone(); //克隆
                            console.log('克隆的盒子 left 和 top',e.clientX - e.offsetX,e.clientY - e.offsetY)
                            $clone.addClass('draging').css({ //对克隆的盒子设置类名以及位置
                                left: e.clientX - e.offsetX,
                                top: e.clientY - e.offsetY,
                            });
                            $('#canvasBox').append($clone); //追加到box里面
                            $(this).addClass('moving').html(''); //被克隆的元素添加类移除内容
                            $('#canvasBox').on('mousemove', function (e) { //对克隆的盒子进行拖拽
                                $clone.css({
                                    left: e.pageX - $(this).offset().left - disx,
                                    top: e.pageY - $(this).offset().top - disy + 20
                                })
                                clearTimeout(myTiming);//清除显示定时器
                            });

                            $clone.on('mouseup', function () {
                                    $('#canvasBox').off('mousemove'); //取消mousemove事件
                                    let minValue = 1000; //初始化最小值，用来存储所有盒子的最小值
                                    let minObj;

                                    $('#canvasBox .item').not(':last').each(function () { //不包括克隆的那个盒子
                                        let grandPosition = $(this).parent().parent().position()
                                        let thisPosition = $(this).position()
                                        let smalldistance = Math.sqrt(Math.pow($clone.position().left - thisPosition.left - grandPosition.left, 2) + Math.pow($clone.position().top - thisPosition.top - grandPosition.top, 2)); //利用勾股定理获取每一个盒子离克隆出来的盒子的距离
                                        if (smalldistance < minValue) { //比较
                                            minValue = smalldistance; //获取最小值
                                            minObj = {
                                                dom: $(this),
                                                position: {
                                                    left: thisPosition.left + grandPosition.left,
                                                    top: thisPosition.top + grandPosition.top,
                                                }
                                            } //距离最短的dom + 定位
                                        }
                                    });
                                    let minData = minObj.dom[0].dataset;//获取距离最短的dom标识
                                    let nowData = $(that)[0].dataset;//获取要拖拽的标识

                                    if ((minData.parent == nowData.parent) && (minData.position == nowData.position)) { //如果当前最小距离的那个盒子和拖拽的盒子索引相等的话，归位。
                                        $clone.animate($(that).position(), 400, function () {
                                            $(that).removeClass('moving').html($clone.html()); //恢复被克隆盒子的相关样式
                                            $(this).remove(); //移除被克隆的盒子
                                            Astop = true;
                                        });
                                    } else {
                                        toParent = minData.parent;//要跳到的div 标识，判断是否是相同div内拖拽
                                        let $minbox = minObj.dom; //最小索引的盒子
                                        let $clone2 = $minbox.clone(); //克隆一个最小盒子的副本，添加相关样式
                                        $clone2.addClass('draging').css({
                                            left: minObj.position.left,
                                            top: minObj.position.top
                                        })
                                        $('#canvasBox').append($clone2); //追加
                                        $minbox.addClass('moving').html('');
                                        $clone.animate(minObj.position, 400, function () { //克隆的内容运动到最小索引的盒子的位置
                                            $minbox.removeClass('moving').html($clone.html()); //移除相关样式，添加内容
                                            $clone.remove(); //移除克隆的盒子
                                            Astop = true;
                                        });
                                        $clone2.animate(animatePosition, 400, function () {
                                                $(that).removeClass('moving').html($clone2.html());
                                                $clone2.remove();
                                                Astop = true;
                                            }
                                        );
                                    }
                                }
                            )
                            ;
                        }
                        return false;
                    }
                )
                ;
            }

            //添加 设备 拖拽事件
            function addFun2() {
                let Astop = true;
                let Parent = '', toParent = '';
                $('#all .item').on('mousedown', function (e) {
                        if (Astop) {
                            if (e.offsetX <= 10 || e.offsetY <= 10) return //防止误操作 故改为距离边框 4 才可进行拖拽操作
                            Parent = $(this)[0].dataset.parent //当前要替换的dom 的 父ID
                            Astop = false;
                            let that = this;
                            let disx = e.offsetX; //获取的拖拽过程的短线的长度（鼠标的位置离盒子边缘的位置）
                            let disy = e.offsetY;
                            let disx2 = e.clientX; //获取的拖拽过程的短线的长度（鼠标的位置离盒子边缘的位置）
                            let disy2 = e.clientY;
                            /*获取当前拖拽的dom的页面位置 begin*/
                            let thatGrandPosition = $(that).parent().parent().position()
                            let thatPosition = $(that).position()
                            let animatePosition = {
                                top: thatGrandPosition.top + thatPosition.top,
                                left: thatGrandPosition.left + thatPosition.left,
                            }
                            /*获取当前拖拽的dom的页面位置 end*/
                            let $clone = $(this).clone(); //克隆
                            $clone.addClass('draging').css({ //对克隆的盒子设置类名以及位置
                                left: e.clientX - e.offsetX,
                                top: e.clientY - e.offsetY,
                            });
                            $('#all').append($clone); //追加到box里面
                            $(this).addClass('moving').html(''); //被克隆的元素添加类移除内容
                            $('#all').on('mousemove', function (e) { //对克隆的盒子进行拖拽
                                $clone.css({
                                    left: e.pageX - $(this).offset().left - disx,
                                    top: e.pageY - $(this).offset().top - disy + 20
                                })
                                clearTimeout(myTiming);//清除显示定时器
                            });

                            $clone.on('mouseup', function () {
                                    $('#all').off('mousemove'); //取消mousemove事件
                                    let minValue = 1000; //初始化最小值，用来存储所有盒子的最小值
                                    let minObj;

                                    $('#all .item').not(':last').each(function () { //不包括克隆的那个盒子
                                        let grandPosition = $(this).parent().parent().position()
                                        let thisPosition = $(this).position()
                                        let smalldistance = Math.sqrt(Math.pow($clone.position().left - thisPosition.left - grandPosition.left, 2) + Math.pow($clone.position().top - thisPosition.top - grandPosition.top, 2)); //利用勾股定理获取每一个盒子离克隆出来的盒子的距离
                                        if (smalldistance < minValue) { //比较
                                            minValue = smalldistance; //获取最小值
                                            minObj = {
                                                dom: $(this),
                                                position: {
                                                    left: thisPosition.left + grandPosition.left,
                                                    top: thisPosition.top + grandPosition.top,
                                                }
                                            } //距离最短的dom + 定位
                                        }
                                    });
                                    let minData = minObj.dom[0].dataset;//获取距离最短的dom标识
                                    let nowData = $(that)[0].dataset;//获取要拖拽的标识

                                    if ((minData.parent == nowData.parent) && (minData.position == nowData.position)) { //如果当前最小距离的那个盒子和拖拽的盒子索引相等的话，归位。
                                        $clone.animate($(that).position(), 400, function () {
                                            $(that).removeClass('moving').html($clone.html()); //恢复被克隆盒子的相关样式
                                            $(this).remove(); //移除被克隆的盒子
                                            Astop = true;
                                        });
                                    } else {
                                        toParent = minData.parent;//要跳到的div 标识，判断是否是相同div内拖拽
                                        let $minbox = minObj.dom; //最小索引的盒子
                                        let $clone2 = $minbox.clone(); //克隆一个最小盒子的副本，添加相关样式
                                        $clone2.addClass('draging').css({
                                            left: minObj.position.left,
                                            top: minObj.position.top
                                        })
                                        $('#all').append($clone2); //追加
                                        $minbox.addClass('moving').html('');
                                        $clone.animate(minObj.position, 400, function () { //克隆的内容运动到最小索引的盒子的位置
                                            $minbox.removeClass('moving').html($clone.html()); //移除相关样式，添加内容
                                            $clone.remove(); //移除克隆的盒子
                                            Astop = true;
                                        });
                                        $clone2.animate(animatePosition, 400, function () {
                                                $(that).removeClass('moving').html($clone2.html());
                                                $clone2.remove();
                                                Astop = true;
                                            }
                                        );
                                    }
                                }
                            )
                            ;
                        }
                        return false;
                    }
                )
                ;
            }

            addFun2()
            getTableData = function () {
                let nowDeviceJson = []
                //1.获取页面 class='parant',判断有几个分组
                let $parent = $('#canvasBox .parent')

                //2.获取页面 class='item'
                let $item = $('#canvasBox .item')

                for (let i = 0; i < $parent.length; i++) {
                    console.log('获取参数 当前id', i, $($parent[i]).parent()[0].style.left)
                    let obj = {
                        name: $($parent[i]).data('action'),
                        row: $($parent[i]).data('row'),
                        column: $($parent[i]).data('column'),
                        left: $($parent[i]).parent()[0].style.left.substring(0, $($parent[i]).parent()[0].style.left.length - 2),
                        top: $($parent[i]).parent()[0].style.top.substring(0, $($parent[i]).parent()[0].style.top.length - 2),
                        zIndex: 1,
                        scale: scale,
                        childList: []
                    }
                    for (let j = 0; j < $item.length; j++) {
                        //根据 data-parent 分别赋值给不同的组
                        if ($($item[j]).data('parent') == obj.name) {
                            let children = $($item[j])[0].children
                            obj.childList.push({
                                position: $($item[j]).data('position'),
                                obj: children.length > 0 ? {
                                    id: children[0].dataset.id,
                                    name: $($($item[j])[0].children[0]).text(),
                                    status: $($($item[j])[0].children[2]).text() == '运行中' ? 1 : 0
                                } : {}
                            })
                        }
                    }
                    nowDeviceJson.push(obj)
                }
                console.log('页面现有表格数据', nowDeviceJson)
            }

            //页面弹窗数据绑定
            var popData = {
                ip: '',
                memory: '',
                memory_use: '',
                disk: '',
                disk_use: '',
                accept: '',
                send: '',
                user: '',
            }
            Object.defineProperty(popData, 'ip', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.ip').text(val)
                },
            })
            Object.defineProperty(popData, 'memory', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.memory').text(val)
                },
            })
            Object.defineProperty(popData, 'memory_use', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.memory_use').text(val)
                },
            })
            Object.defineProperty(popData, 'disk', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.disk').text(val)
                },
            })
            Object.defineProperty(popData, 'disk_use', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.disk_use').text(val)
                },
            })
            Object.defineProperty(popData, 'accept', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.accept').text(val)
                },
            })
            Object.defineProperty(popData, 'send', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.send').text(val)
                },
            })
            Object.defineProperty(popData, 'user', {
                set: function (val) {
                    console.log('接收到参数', val)
                    $('.user').text(val)
                },
            })

            //鼠标悬浮2秒触发弹窗显示
            $(".item").mouseover(function (e) {
                let left = $(this).offset().left;
                let top = $(this).offset().top;
                $(this).addClass('hoverItem')
                if ($(this)[0].children.length > 0) {
                    myTiming = setTimeout(function () {
                        popData.ip = '123'
                        popData.user = 'mcccc',
                            $('.pop').css({
                                display: 'block',
                                left: left + itemBox.width + 10 + 'px',
                                top: top + 'px',
                                zIndex: 99
                            })
                    }, 1000);
                }
            });
            $(".item").mouseout(function () {
                $(this).removeClass('hoverItem')
                clearTimeout(myTiming);
                $('.pop').css('display', 'none')
            });
        });
    })(jQuery);
</script>
</body>
</html>